#include <stdio.h>
#include "../common/sparse_matrix.h"

int main(void)
{
	int n = 0, nn = 0, i = 0, result = 0;
	double value = 0.0;
	sparse_matrix_lst *sparse_matrix = NULL;
	elem *input_vector = NULL, *output_vector = NULL;

	result = scanf("%d", &n);
	if (result != 1)
	{
		result = printf("\nERROR: not a number\n\n");
		assert(result >= 0);
		return 1;
	}

	if (n <= 0)
	{
		result = printf("\nERROR: Matrix size must be a positive number.\n\n");
		assert(result >= 0);
		return 1;
	}

	nn = n * n;
	sparse_matrix = allocate_sparse_matrix_lst(n);

	for (i = 0; i < nn; i++)
	{
		result = scanf("%lf", &value);
		if (result != 1)
		{
			result = printf("\nERROR: not a number\n\n");
			assert(result >= 0);
			return 1;
		}
		if (value != 0)
		{
			cell_t* cell = (cell_t*)malloc(sizeof(cell_t));
			cell_t* prev_cell = NULL;
			cell->value = value;
			cell->colind = i%n;
			cell->rowind = i/n;
			cell->col_next = NULL;
			cell->row_next = NULL;

			/* rows */
			prev_cell = sparse_matrix->rows[cell->rowind];
			if (prev_cell == NULL)
			{
				sparse_matrix->rows[cell->rowind] = cell;
			}
			else
			{
				while (prev_cell->col_next != NULL)
				{
					prev_cell = prev_cell->col_next;
				}
				prev_cell->col_next = cell;
			}

			/* cols */
			prev_cell = sparse_matrix->cols[cell->colind];
			if (prev_cell == NULL)
			{
				sparse_matrix->cols[cell->colind] = cell;
			}
			else
			{
				while (prev_cell->row_next != NULL)
				{
					prev_cell = prev_cell->row_next;
				}
				prev_cell->row_next = cell;
			}
		}
	}

	input_vector = (elem*)calloc(n, sizeof(elem));
	assert (input_vector != NULL);

	for(i = 0; i < n; i++)
	{
		result = scanf("%lf", &input_vector[i]);
		if (result != 1)
		{
			result = printf("\nERROR: not a number\n\n");
			assert(result >= 0);
			return 1;
		}
	}

	output_vector = (elem*)calloc(n, sizeof(elem));
	mult_sparse_list(sparse_matrix, input_vector, output_vector);

	for (i = 0; i < n; i++)
	{
		result = printf("%lf ", output_vector[i]);
		assert(result >= 0);
	}

	free_sparse_matrix_lst(sparse_matrix);
	free (input_vector);
	free (output_vector);
	return 0;
}
